/**
  ******************************************************************************
  * @file    gt32f030_dma.c
  * @author  GT Application Team
  * @version V1.0.0
  * @date    03-January-2025      
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2022 Giantec Semicondutor Inc</center></h2>
  *
  *             http://www.giantec-semi.com/
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "gt32f030_rcc.h"
#include "gt32f030_dma.h"

 /** @addtogroup GT32F030_StdPeriph_Driver
  * @{
  */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/



/** @defgroup DMA
  * @brief DMA driver modules
  * @{
  */ 

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup DMA_Private_Functions
  * @{
  */ 

/** @defgroup DMA_Init Initialization functions
 *  @brief   Initialization and functions
 *
@verbatim    
 ===============================================================================
              ##### Initialization functions #####
 ===============================================================================
@endverbatim
  * @{
  */
/**
  * @brief  Deinitializes the DMA peripheral registers to their default reset values.
  * @param  None
  * @retval None
  */
void DMA_DeInit(void)
{
	//RCC_PeriphResetCmd(RCC_PeriphReset_DMA, ENABLE);  //DMA no clock control
	//RCC_PeriphResetCmd(RCC_PeriphReset_DMA, DISABLE);	//DMA no clock control
}

/**
  * @brief  Initializes the DMA peripheral according to the specified
  *         parameters in the DMA_InitStruct .
  * @param  DMA_InitStruct: pointer to a BEEP_InitTypeDef structure that contains
  *         the configuration information.
  * @retval None
  */
void DMA_ChannelInit(DMA_ChnInitTypeDef* DMA_ChnInitStruct)
{
	unsigned int ctrl=0,cfg=0;

	ctrl  = (DMA_ChnInitStruct->DMA_BlockTS&0xfff)<<20;
	ctrl |= DMA_ChnInitStruct->DMA_TransferType<<16;
	ctrl |= DMA_ChnInitStruct->DMA_SrcAddr_Dir<<9;
	ctrl |= DMA_ChnInitStruct->DMA_DstAddr_Dir<<7;//DmaCtrl_DstAdr_IncDec<<7;
	ctrl |= DMA_ChnInitStruct->DMA_SrcDataWidth<<4;//DmaCtrl_Src_DataWidth<<4;
	ctrl |= DMA_ChnInitStruct->DMA_DstDataWidth<<1;//DmaCtrl_Dst_DataWidth<<1;
	if(DMA_ChnInitStruct->DMA_Intr_Cmd!=DISABLE)
		ctrl |= 0x1;
	

	cfg  = DMA_ChnInitStruct->DMA_DstHsSelect<<12;//DmaCfg_DstHs_Sel<<12;
	cfg |= DMA_ChnInitStruct->DMA_SrcHsSelect<<8;//DmaCfg_SrcHs_Sel<<8;
	cfg |= DMA_ChnInitStruct->DMA_Prior<<5;
	
	if(DMA_ChnInitStruct->DMA_DstReload_Cmd!=DISABLE)
		cfg |= 0x80000000;
	if(DMA_ChnInitStruct->DMA_SrcReload_Cmd!=DISABLE)
		cfg |= 0x40000000;
	
	if(DMA_ChnInitStruct->DMA_Channel==DMA_Channel0)
	{
		DMA->SAR0=DMA_ChnInitStruct->DMA_SrcAddr;
		DMA->DAR0=DMA_ChnInitStruct->DMA_DstAddr;
    DMA->CTL0 = ctrl;
		DMA->CFG0 = cfg;
	}
	if(DMA_ChnInitStruct->DMA_Channel==DMA_Channel1)
	{
		DMA->SAR0=DMA_ChnInitStruct->DMA_SrcAddr;
		DMA->DAR0=DMA_ChnInitStruct->DMA_DstAddr;
    DMA->CTL1 = ctrl;
		DMA->CFG1 = cfg;
	}
	if(DMA_ChnInitStruct->DMA_Channel==DMA_Channel2)
	{
		DMA->SAR0=DMA_ChnInitStruct->DMA_SrcAddr;
		DMA->DAR0=DMA_ChnInitStruct->DMA_DstAddr;
    DMA->CTL2 = ctrl;
		DMA->CFG2 = cfg;
	}
}

void DMA_HSInit(DMA_HSInitTypeDef* DMA_HSInitStruct)
{
	unsigned int hs;

	hs  = DMA_HSInitStruct->DMA_HS5Source<<18;
	hs |= DMA_HSInitStruct->DMA_HS4Source<<16;
	hs |= DMA_HSInitStruct->DMA_HS3Source<<10;
	hs |= DMA_HSInitStruct->DMA_HS2Source<<8;
	hs |= DMA_HSInitStruct->DMA_HS1Source<<2;
	hs |= DMA_HSInitStruct->DMA_HS0Source;
  DMA_CHSEL = hs;
}


void DMA_Cmd(FunctionalState NewState)
{
if(NewState!=DISABLE)
		DMA->CFG= 1;
}
void DMA_ChannelCmd(DMAChannel_TypeDef chn,FunctionalState NewState)
{
	//unsigned int it=DMA->CHNEN;
	
	if(NewState!=DISABLE)
	{
		//it=it+(it<<3);
		if(chn==DMA_Channel0)
			DMA->CHNEN |= DMA_Channel0+0x08;
		if(chn==DMA_Channel1)
				DMA->CHNEN |= DMA_Channel1+0x10;
		if(chn==DMA_Channel2)
				DMA->CHNEN |= DMA_Channel2+0x20;
	}
	else
	{
		//it=it+(it<<3);
		if(chn==DMA_Channel0)
			DMA->CHNEN &= (~(uint32_t)(DMA_Channel0+8));
		if(chn==DMA_Channel1)
			DMA->CHNEN &= (~(uint32_t)(DMA_Channel1+0x10));
		if(chn==DMA_Channel2)
			DMA->CHNEN &= (~(uint32_t)(DMA_Channel2+0x20));		
	}
}

void DMA_ITConfig(DMAIT_TypeDef DMA_IT, DMAChannel_TypeDef chn, FunctionalState NewState)
{	
	if(DMA_IT==DMAIT_Tfr)
	{
		//unsigned int it=DMA->TFTINT_EN;
		 if (NewState != DISABLE)
		 {	
			if(chn==DMA_Channel0)
				DMA->TFRINT_EN |=DMA_Channel0+0x08;
			if(chn==DMA_Channel1)
				DMA->TFRINT_EN |=DMA_Channel1+0x10;
			if(chn==DMA_Channel2)
				DMA->TFRINT_EN |=DMA_Channel2+0x20;
		 }
		 else
		 {
			if(chn==DMA_Channel0)
				DMA->TFRINT_EN &=(~(uint32_t)(DMA_Channel0+0x08));
			if(chn==DMA_Channel1)
				DMA->TFRINT_EN &=(~(uint32_t)(DMA_Channel1+0x10));
			if(chn==DMA_Channel2)
				DMA->TFRINT_EN &=(~(uint32_t)(DMA_Channel2+0x20));
		 }
	}

	if(DMA_IT==DMAIT_Block)
	{
		//unsigned int it=DMA->BLOCKINT_EN;
		if (NewState != DISABLE)
		{
		    /*
			if(chn==DMA_Channel0)
				DMA->BLOCKINT_EN |=(~(uint32_t)(DMA_Channel0+0x08));
			if(chn==DMA_Channel1)
				DMA->BLOCKINT_EN |=(~(uint32_t)(DMA_Channel0+0x10));
			if(chn==DMA_Channel2)
				DMA->BLOCKINT_EN |=(~(uint32_t)(DMA_Channel0+0x20));
		    */
            if (chn == DMA_Channel0) {
              DMA->BLOCKINT_EN |= DMA_Channel0 + 0x08;
            } else if (chn == DMA_Channel1) {
              DMA->BLOCKINT_EN |= DMA_Channel1 + 0x10;
            } else if (chn == DMA_Channel2) {
              DMA->BLOCKINT_EN |= DMA_Channel2 + 0x20;
            }
		}
		else
		{
			if(chn==DMA_Channel0)
				DMA->BLOCKINT_EN &=(~(uint32_t)(DMA_Channel0+0x08));
			if(chn==DMA_Channel1)
				DMA->BLOCKINT_EN &=(~(uint32_t)(DMA_Channel1+0x10));
			if(chn==DMA_Channel2)
				DMA->BLOCKINT_EN &=(~(uint32_t)(DMA_Channel2+0x20));
		}
	}		

	if(DMA_IT==DMAIT_Error)
	{
		//unsigned int it=DMA->ERRINT_EN;
		if (NewState != DISABLE)
		{
			/*
			if(chn==DMA_Channel0)
				DMA->ERRINT_EN |=(~(uint32_t)(DMA_Channel0+0x08));
			if(chn==DMA_Channel1)
				DMA->ERRINT_EN |=(~(uint32_t)(DMA_Channel1+0x10));
			if(chn==DMA_Channel2)
				DMA->ERRINT_EN |=(~(uint32_t)(DMA_Channel2+0x20));
			*/
            if (chn == DMA_Channel0) {
              DMA->ERRINT_EN |= DMA_Channel0 + 0x08;
            } else if (chn == DMA_Channel1) {
              DMA->ERRINT_EN |= DMA_Channel1 + 0x10;
            } else if (chn == DMA_Channel2) {
              DMA->ERRINT_EN |= DMA_Channel2 + 0x20;
            }
		}
		else
		{
			if(chn==DMA_Channel0)
				DMA->ERRINT_EN &=(~(uint32_t)(DMA_Channel0+0x08));
			if(chn==DMA_Channel1)
				DMA->ERRINT_EN &=(~(uint32_t)(DMA_Channel1+0x10));
			if(chn==DMA_Channel2)
				DMA->ERRINT_EN &=(~(uint32_t)(DMA_Channel2+0x20));
		}
	}
}

/**
  * @brief  Gets the pending bit of the DMA interrupt.
  * @param  DMA_IT: specifies the DMA interrupt source to check.
  * @param  chn: specifies the DMA channel to check.
  * @retval The pending bit status of the DMA interrupt.
  */
FlagStatus DMA_GetPendingBit(DMAIT_TypeDef DMA_IT, DMAChannel_TypeDef chn) {
  FlagStatus status = RESET;
  uint32_t itreg = 0;

  if (DMA_IT == DMAIT_Tfr) {
    itreg = DMA->STSTFR;
  } else if (DMA_IT == DMAIT_Block) {
    itreg = DMA->STSBLOCK;
  } else if (DMA_IT == DMAIT_Error) {
    itreg = DMA->STSERR;
  }

  if (chn == DMA_Channel0) {
    if ((itreg & 0x01) != (uint32_t)RESET) {
      status = SET;
	} else {
      status = RESET;
    }
  } else if (chn == DMA_Channel1) {
    if ((itreg & 0x02) != (uint32_t)RESET) {
      status = SET;
	} else {
      status = RESET;
    }
  } else if (chn == DMA_Channel2) {
    if ((itreg & 0x04) != (uint32_t)RESET) {
      status = SET;
	} else {
      status = RESET;
    }
  }

  return status;
}

/**
  * @brief  Initializes the DMA peripheral according to the specified
  *         parameters in the DMA_InitStruct .
  * @param  DMA_InitStruct: pointer to a BEEP_InitTypeDef structure that contains
  *         the configuration information.
  * @retval None
  */ 

void DMA_ClearPendingBit(DMAIT_TypeDef DMA_IT, DMAChannel_TypeDef chn)
{

	if(DMA_IT==DMAIT_Tfr)
	{
		if(chn==DMA_Channel0)
			DMA->CLRTFR |=0x01;
		if(chn==DMA_Channel1)
			DMA->CLRTFR |=0x02;
		if(chn==DMA_Channel2)
			DMA->CLRTFR |=0x04;
	}

	if(DMA_IT==DMAIT_Block)
	{
		/*
		unsigned int it=DMA->CLRBLOCK;
		*/
		if(chn==DMA_Channel0)
			DMA->CLRBLOCK |=0x01;
		if(chn==DMA_Channel1)
			DMA->CLRBLOCK |=0x02;
		if(chn==DMA_Channel2)
			DMA->CLRBLOCK |=0x04;
	}		

	if(DMA_IT==DMAIT_Error)
	{
		/*
		unsigned int it=DMA->ERRINT_EN;
		*/
		if(chn==DMA_Channel0)
			DMA->CLRERR |=0x01;
		if(chn==DMA_Channel1)
			DMA->CLRERR |=0x02;
		if(chn==DMA_Channel2)
			DMA->CLRERR |=0x04;
	}


}


/**
  * @}  
  */ 

/**
  * @}  
  */

/**
  * @}  
  */ 

/**
  * @}
  */ 
/************************ (C) COPYRIGHT Giantec Semicondutor Inc *****END OF FILE****/
